Passed
Push — dependabot/npm_and_yarn/dev/st... ( 917c39...79f3f4 )
by
unknown
12:32 queued 07:14
created

queries.ts ➔ hasKey   A

Complexity

Conditions 1

Size

Total Lines 11
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 6
dl 0
loc 11
rs 10
c 0
b 0
f 0
1
/**
2
 * Shortcut function that returns the id attribute of an object.
3
 * @param item
4
 */
5
export function getId<T extends { id: number }>(item: T): number {
6
  return item.id;
7
}
8
9
export function identity<T>(value: T): T {
10
  return value;
11
}
12
13
/**
14
 * Returns true as long as the value passed to it is not null or undefined.
15
 * Can be used to filter nulls and undefined values out of an array.
16
 * @param item
17
 */
18
export function notEmpty<T>(value: T | null | undefined): value is T {
19
  return value !== null && value !== undefined;
20
}
21
22
export function stringNotEmpty(value: string | null): value is string {
23
  return notEmpty(value) && value.length > 0;
24
}
25
26
/**
27
 * From an array of objects, return the first object with a specific id value.
28
 * @param objs
29
 * @param id
30
 */
31
export function find<T extends { id: number }>(
32
  objs: T[],
33
  id: number,
34
): T | null {
35
  const found = objs.filter(item => item.id === id);
36
  return found.length > 0 ? found[0] : null;
37
}
38
39
/**
40
 * Return all objects from array with the specified key-value attribute.
41
 * @param objs
42
 * @param prop
43
 * @param value
44
 */
45
export function where<T, K extends keyof T>(
46
  objs: T[],
47
  prop: K,
48
  value: any,
49
): T[] {
50
  return objs.filter(obj => prop in obj && obj[prop] === value);
51
}
52
53
/**
54
 * Return first object from array with the specified key-value attribute.
55
 * @param objs
56
 * @param prop
57
 * @param value
58
 */
59
export function whereFirst<T, K extends keyof T>(
60
  objs: T[],
61
  prop: K,
62
  value: any,
63
): T {
64
  return where(objs, prop, value)[0];
65
}
66
67
/**
68
 * Map each key-value attribute of an object into an array
69
 * @param object
70
 * @param mapFn
71
 */
72
export function objectMap<A, B>(
73
  object: {
74
    [key: string]: A;
75
  },
76
  mapFn: (key: string, value: A) => B,
77
): B[] {
78
  return Object.keys(object).reduce((result: B[], key: string): B[] => {
79
    result.push(mapFn(key, object[key]));
80
    return result;
81
  }, []);
82
}
83
84
interface IndexedObject<T> {
85
  [key: string]: T;
86
}
87
88
/**
89
 * Maps an array of items into an object, with each transformed into an attribute
90
 * @param items array of objects
91
 * @param keyFn Function that returns a unique key for each object. Typically the getId function.
92
 * @param valFn Function that returns a new value for each object.
93
 */
94
export function mapToObjectTrans<A, B>(
95
  items: A[],
96
  keyFn: (item: A) => string | number,
97
  valFn: (item: A) => B,
98
): IndexedObject<B> {
99
  return items.reduce((result: IndexedObject<B>, item: A): IndexedObject<B> => {
100
    const key = keyFn(item);
101
    result[key] = valFn(item);
102
    return result;
103
  }, {});
104
}
105
106
/**
107
 * Maps an array of items into an object, with each item set as an attribute.
108
 * @param items array of objects
109
 * @param keyFn Function that returns a unique key for each object. Typically the getId function.
110
 */
111
export function mapToObject<T>(
112
  items: T[],
113
  keyFn: (item: T) => string | number,
114
): IndexedObject<T> {
115
  return mapToObjectTrans(items, keyFn, (item): T => item);
116
}
117
118
/**
119
 * Checks if an object has an attribute with a particular key
120
 * @param object
121
 * @param key
122
 */
123
export function hasKey<T>(
124
  object: { [key: string]: T },
125
  key: string | number,
126
): boolean {
127
  return Object.prototype.hasOwnProperty.call(object, key);
128
}
129
130
/**
131
 * Returns the value at the specified key. If the key is not present, throws an error.
132
 * @param object
133
 * @param key
134
 * @param errorMessage
135
 */
136
export function getOrThrowError<T>(
137
  object: { [key: string]: T },
138
  key: string | number,
139
  errorMessage: string,
140
): T {
141
  if (!hasKey(object, key)) {
142
    throw new Error(errorMessage);
143
  }
144
  return object[key];
145
}
146
147
/** Return a copy of the object with specific property removed */
148
export function deleteProperty<T>(
149
  obj: IndexedObject<T>,
150
  key: string | number,
151
): IndexedObject<T> {
152
  const { [key]: _, ...newObj } = obj;
153
  return newObj;
154
}
155
156
/**
157
 * Iterate through the properties of the object, checking which return true for the filterFunction.
158
 * Return a copy of the object, without the properties that don't pass the filter.
159
 */
160
export function filterObjectProps<T>(
161
  obj: IndexedObject<T>,
162
  filter: (value: T) => boolean,
163
): IndexedObject<T> {
164
  return Object.entries(obj).reduce(
165
    (newObj: IndexedObject<T>, [key, value]): IndexedObject<T> => {
166
      if (filter(value)) {
167
        newObj[key] = value;
168
      }
169
      return newObj;
170
    },
171
    {},
172
  );
173
}
174
175
/** Return a copy of the list with duplicate elements removed */
176
export function uniq<T>(x: T[]): T[] {
177
  return Array.from(new Set(x));
178
}
179